package net.kong.yumo.utils;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class EncrypAES {

	private static String defaultCharset="utf-8";
	
	/** 默认密钥，实际项目中可配置注入或数据库读取 */
	private static String defaultKey = "zhiyuhuan-108689";
	                                 

	/** 加密工具 */
	private Cipher encryptCipher = null;

	/** 解密工具 */
	private Cipher decryptCipher = null;
	
	private static EncrypAES instance = new EncrypAES();

	public static EncrypAES getInstance() {
		return instance;
	}
	
	private EncrypAES(){

	}

	public void initKey(){
		initKey(defaultKey,defaultCharset);
	}
	
	public void initKey(String charset){
		initKey(defaultKey,charset);
	}
	
	public void initKey(String keyvalue,String charset){
		defaultCharset=charset;
		Security.addProvider(new com.sun.crypto.provider.SunJCE());
		if(keyvalue==null)
			keyvalue=defaultKey;
		byte[] arrBTmp=null;
		try {
			arrBTmp = keyvalue.getBytes(charset);
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		// 创建一个空的length位字节数组（默认值为0）
		byte[] arrB = new byte[16];

		// 将原始字节数组转换为8位
		for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
			arrB[i] = arrBTmp[i];
		}
		// 生成密钥
		Key key = new javax.crypto.spec.SecretKeySpec(arrB, "AES");

		// 生成Cipher对象,指定其支持的DES算法
		try {
			encryptCipher = Cipher.getInstance("AES");
			encryptCipher.init(Cipher.ENCRYPT_MODE, key);

			decryptCipher = Cipher.getInstance("AES");
			decryptCipher.init(Cipher.DECRYPT_MODE, key);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		}	
	}
	
	/**
	 * 对字符串加密
	 * 
	 * @param str
	 * @return
	 * @throws InvalidKeyException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 */
	public byte[] Encrytor(String str) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		byte[] src = null;
		try {
			src = str.getBytes(defaultCharset);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		return encryptCipher.doFinal(src);
	}

	/**
	 * 对字符串解密
	 * 
	 * @param buff
	 * @return
	 * @throws InvalidKeyException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 */
	public byte[] Decryptor(byte[] buff) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		return decryptCipher.doFinal(buff);
	}

	/**
	 * @param args
	 * @throws NoSuchPaddingException
	 * @throws NoSuchAlgorithmException
	 * @throws BadPaddingException
	 * @throws IllegalBlockSizeException
	 * @throws InvalidKeyException
	 */
	public static void main(String[] args) throws Exception {
		String encoding="utf-8";
		EncrypAES en = EncrypAES.getInstance();
		en.initKey();
		
		String [] str=new String[]{
				"床强明月光，疑是地上霜。一道残阳铺水中，半江瑟瑟半江红。留连戏蝶时时舞，自在娇莺恰恰啼。",
				"神秘面纱。",
				"402881e55210b5d8015210b97c6f0002",
				"",
				"8月31日晚上BTV体育台《足球100分》节目中，前国安球员南方、《搜达足球》总编辑刘晶捷、媒体人朱煜明担任嘉宾，和主持人魏翊东一起谈论了联赛的争冠、保级形势."
				};
		
		for(int i=0;i<str.length;i++){
			
			System.out.println("/*------------------------------------------------第 "+(i+1)+  " 条信息------------------------------------------------*/");
			
		    byte enB[]=en.Encrytor(str[i]);
		    String s=ToolUtil.byte2HexStr(enB);
			System.out.println("####(JAVA)加密之后的十六进制字符串：\r\n"+new String(s));
		    
			System.out.println("\r\n");
		    byte [] enB1=ToolUtil.hexStr2Byte(s);
			System.out.println("####(JAVA)解密之后的明文：\r\n"+new String(en.Decryptor(enB1),encoding));
			System.out.println("\r\n");
		}
		
		
		String tmp="08B919D0055C62B2FD6F85882F002A5F";
	    byte [] enB1=ToolUtil.hexStr2Byte(tmp);
		System.out.println("####(JAVA)解密之后的明文：\r\n"+new String(en.Decryptor(enB1),encoding));
		System.out.println("\r\n");
	
	}
}